package com.puzzlebazar.client.puzzleinfo;

import com.puzzlebazar.client.main.control.MainController;
import com.puzzlebazar.client.main.control.NamedStateSubControllerImpl;
import com.puzzlebazar.client.main.control.PuzzleTokenFactory;
import com.puzzlebazar.client.main.control.SubStateTokenFactory;
import com.puzzlebazar.client.main.view.TabbedView;
import com.puzzlebazar.client.user.UserInfo;
import com.puzzlebazar.client.user.UserModel;
import com.puzzlebazar.client.util.Capabilities;
import com.puzzlebazar.client.util.Observable;
import com.puzzlebazar.client.util.Observer;

public class PuzzleInfoController extends NamedStateSubControllerImpl implements PuzzleTokenFactory, Observer {

	public static final String DEFAULT_STATE_NAME = DetailsSubstate.STATE_NAME;
	
	
	private final DetailsSubstate detailsState;	
	private final MySolutionsSubstate mySolutionsState;	
	private final SolversSubstate solversState;	
	private final StatisticsSubstate statisticState;	

	private final PuzzleInfoModel model;
	
	/**
	 * Creates a controller for puzzle information pages
	 * 
	 * @param model The associated model
	 * @param view The associated view
	 * @param parentController The parent of this sub controller
	 * @param tokenFactory The object used to build tokens for substates
	 */
	public PuzzleInfoController(PuzzleInfoModel model, TabbedView view, MainController parentController, SubStateTokenFactory tokenFactory ) {
		super(parentController, tokenFactory);
		
		this.model = model;
		
		detailsState = new DetailsSubstate( model, view, this );
		mySolutionsState = new MySolutionsSubstate( model, view, this );
		solversState = new SolversSubstate( model, view, this );
		statisticState = new StatisticsSubstate( model, view, this );
		
		model.addObserver( this );
		UserModel.get().addObserver( this );
	}
	
	@Override
	public void enter() {
		super.enter();
		model.reload();
	}

	@Override
	public void exit() {
		super.exit();
		model.notifyObservers();
	}
	
	@Override
	public void gotoDefaultState() {
		if( !leaveCurrentState() ) return;
		enterState( detailsState );
	}

	@Override
	public String getDefaultStateName() {
		return DEFAULT_STATE_NAME;
	}

	@Override
	public String getEditPuzzleToken(String puzzleInfoKey) {
		return ((MainController)parentController).getEditPuzzleToken(puzzleInfoKey);
	}

	@Override
	public String getPlayPuzzleToken(String puzzleInfoKey) {
		return ((MainController)parentController).getPlayPuzzleToken(puzzleInfoKey);
	}

	@Override
	public String getPuzzleInfoToken(String puzzleInfoKey) {
		return ((MainController)parentController).getPuzzleInfoToken(puzzleInfoKey);
	}

	@Override
	public String getTutorialInfoToken(String puzzleInfoKey) {
		return ((MainController)parentController).getTutorialInfoToken(puzzleInfoKey);
	}

	@Override
	public String getContinueHistoryToken(String historyInfoKey) {
		return ((MainController)parentController).getContinueHistoryToken(historyInfoKey);
	}


	@Override
	public String getViewHistoryToken(String historyInfoKey) {
		return ((MainController)parentController).getViewHistoryToken(historyInfoKey);
	}

	@Override
	public String getEditTutorialToken(String historyInfoKey) {
		return ((MainController)parentController).getEditTutorialToken(historyInfoKey);
	}

	@Override
	public String getViewTutorialToken(String historyInfoKey) {
		return ((MainController)parentController).getViewTutorialToken(historyInfoKey);
	}

	@Override
	public void release() {

		model.deleteObserver( this );
		UserModel.get().deleteObserver( this );
		
		detailsState.release();
		mySolutionsState.release();
		solversState.release();
		statisticState.release();
	}

	@Override
	public void update(Observable observable, Object arg) {

		UserInfo userInfo = UserModel.get().getUserInfo();
		mySolutionsState.setTabVisible( 
				Capabilities.canHaveSolutions( model.getPuzzleInfo(), userInfo ) );
		solversState.setTabVisible( 
				Capabilities.canSeeSolvers( model.getPuzzleInfo(), userInfo ) );
		statisticState.setTabVisible( 
				Capabilities.canSeeStatistics( model.getPuzzleInfo(), userInfo ) );		
	}
}
